import bean.User;
import utils.DateUtils;
import utils.PrintlnUtils;

import java.util.LinkedHashMap;

/*

数据结构：数组+链表（巧妙！）
https://blog.csdn.net/cumtwyc/article/details/51638434

06 | 链表（上）：如何实现LRU缓存淘汰算法?
https://blog.csdn.net/ChinaDragon10/article/details/109437401

 */
public class TestLinkedHashMap {
    public static void main(String[] args) {
        testLinkedHashMap();
    }

    private static void testLinkedHashMap() {

        /*
            如果存储同样多的数据，双向链表要比单链表占用更多的内存空间。虽然两个指针比较浪费存储空间，但可以支持双向遍历，这样也带来了双向链表操作的灵活性

             LinkedHashMap 的实现原理，用到了双向链表这种数据结构。

             重点：
             用空间换时间的设计思想。当内存空间充足的时候，如果我们更加追求代码的执行速度，我们就可以选择空间复杂度相对较高、但时间复杂度相对很低的算法或者数据结构。
             相反，如果内存比较紧缺，比如代码跑在手机或者单片机上，这个时候，就要反过来用时间换空间的设计思路。

         */

        int initialCapacity = 3000_0000;
        LinkedHashMap<String, Object> stringObjectLinkedHashMap = new LinkedHashMap<>(initialCapacity);
        long startTime2 = System.currentTimeMillis();
        PrintlnUtils.println("开始时间 " + DateUtils.timestamp2FormatedStr(startTime2) + "  startTime2 = " + startTime2);
        for (int i = 0; i < initialCapacity; i++) {
            User user = new User();
            user.setAge(i);
            user.setId(i);
            user.setName("用户 " + i);
            stringObjectLinkedHashMap.put("" + i, user);
        }
        long endTime2 = System.currentTimeMillis();
        PrintlnUtils.println("结束时间 " + DateUtils.timestamp2FormatedStr(endTime2) + "  endTime2   = " + endTime2);

        long countMilisTime2 = endTime2 - startTime2;
        PrintlnUtils.println("耗时 " + countMilisTime2 + " 毫秒");

        int countTime2 = (int) (countMilisTime2 * 1.0 / 1000);
        PrintlnUtils.println("耗时 " + countTime2 + " 秒");

         /*
            see to TestArray  没有报内存溢出
         */

        /*

            虽然初始化LinkedHashMap时指定定了 内存，但是报错：内存溢出

              LinkedHashMap 的实现原理，用到了双向链表这种数据结构。 双向链表要比单链表占用更多的内存空间

            Java heap space 堆内存空间

             Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
            at java.base/java.lang.StringConcatHelper.newString(StringConcatHelper.java:387)
            at java.base/java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(DirectMethodHandle$Holder)
            at java.base/java.lang.invoke.LambdaForm$MH/0x0000000800bb8c40.invoke(LambdaForm$MH)
            at java.base/java.lang.invoke.Invokers$Holder.linkToTargetMethod(Invokers$Holder)
            at TestLinkedHashMap.testLinkedHashMap(TestLinkedHashMap.java:28)
            at TestLinkedHashMap.main(TestLinkedHashMap.java:15)


        */

    }
}
